/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.metasketch.model.loader.links;

import java.util.Collection;
import java.util.HashSet;

import org.metasketch.model.loader.GraphNode;
import org.metasketch.model.loader.IGetLinkLogic;

/**
 *
 * @author guilhermegrg
 */
public class HumanActivityAndGroupLinkProvider extends IGetLinkLogic {

    protected boolean isVisited(GraphNode node, Collection<String> visited) {
        String id = (String) node.getId();
        return visited.contains(id);
    }

    @Override
    public boolean canProcess(GraphNode node, String type, String targetType) {
        if (type.equalsIgnoreCase("HumanActivity") || type.equalsIgnoreCase("HumanActivityGroup")) {
            return true;
        }
        return false;
    }

    @Override
    public Collection<GraphNode> getLinks(GraphNode node, String type) {

        Collection<GraphNode> links = new HashSet();
        Collection<String> visited = new HashSet();
        visited.add(node.getId());

        getDirectLinkedNodesAlsoInRelatedGroups(node, links, type, visited);

        //get containing links and process
        Collection<GraphNode> groups = new HashSet();


        getContainingGroupsTreetructure(node, groups);

        for (GraphNode group : groups) {
            String gtype = group.getType();
            if (gtype.equalsIgnoreCase("HumanActivity")) {
                if (!visited.contains(group)) {
                    if (type == null || gtype.equals(type)) {
                        links.add(group);
                    }

                }
                continue;
            }
            getDirectLinkedNodesNoRelatedGroups(group, links, type, visited);
        }
        return links;

    }

    public void getDirectLinkedNodesAlsoInRelatedGroups(GraphNode node, Collection<GraphNode> links, String type, Collection<String> visited) {
        Collection<GraphNode> directLinks = gdb.getDirectRelatedNodes(node);
        for (GraphNode link : directLinks) {
            if (isVisited(link, visited)) {
                continue;
            }
            visited.add(node.getId());

            String ntype = link.getType();
            if (type == null || ntype.equals(type)) {
                links.add(link);
            }

            if (ntype.equalsIgnoreCase("HumanActivityGroup")) {
                getContainedLinks(link, links, visited, type);
            }

        }



//        String nodeType= (String) node.getProperty("id");

        directLinks = gdb.getContainedNodes(node);
        for (GraphNode link : directLinks) {
            if (isVisited(link, visited)) {
                continue;
            }
            visited.add( node.getId() ) ;

            String ntype = (String) (link.getType());
            if (type == null || ntype.equals(type)) {
                links.add(link);
            }

            if (ntype.equalsIgnoreCase("HumanActivityGroup")) {
                getContainedLinks(link, links, visited, type);
            }

        }

    }

    public void getDirectLinkedNodesNoRelatedGroups(GraphNode node, Collection<GraphNode> links, String type, Collection<String> visited) {
        Collection<GraphNode> directLinks = gdb.getDirectRelatedNodes(node);
        for (GraphNode link : directLinks) {
            if (isVisited(link, visited)) {
                continue;
            }
            visited.add(node.getId());

            String ntype = link.getType();
            if (type == null || ntype.equals(type)) {
                links.add(link);
            }

            if (ntype.equalsIgnoreCase("HumanActivityGroup")) {
                getContainedLinks(link, links, visited, type);
            }

        }



        String nodeType = node.getId();
        if (!nodeType.equalsIgnoreCase("HumanActivity")) {
            return;
        }

        directLinks = gdb.getContainedNodes(node);
        for (GraphNode link : directLinks) {
            if (isVisited(link, visited)) {
                continue;
            }
            visited.add(node.getId());

            String ntype = link.getType();
            if (type == null || ntype.equals(type)) {
                links.add(link);
            }

            if (ntype.equalsIgnoreCase("HumanActivityGroup")) {
                getContainedLinks(link, links, visited, type);
            }

        }

    }

    protected void getContainingGroupsTreetructure(GraphNode node, Collection<GraphNode> groups) {
        String type = node.getType();
        Collection<GraphNode> containing = gdb.getContainingNodes(node);
        for (GraphNode link : containing) {
            if (!groups.contains(link)) {
                groups.add(link);
            }


            String gtype = node.getType();
            if (gtype.equalsIgnoreCase("HumanActivity")) {
                continue;
            }

            getContainingGroupsTreetructure(link, groups);
        }
    }

    protected void getContainedLinks(GraphNode node, Collection<GraphNode> links, Collection<String> visited, String type) {
        Collection<GraphNode> contained = gdb.getContainedNodes(node);


        for (GraphNode link : contained) {
            if (isVisited(link, visited)) {
                continue;
            }
            visited.add(node.getId());


            String ntype = link.getType();
            if (type == null || ntype.equals(type)) {
                links.add(link);
            }
//            links.add(link);
            String gtype = link.getType();


            if (gtype.equals("HumanActivityGroup")) {
                getContainedLinks(link, links, visited, type);

            }
        }
    }
}
